<template>
    <div>
        <el-dropdown>
            <el-button size="small"> 选择图片<i class="el-icon-arrow-down el-icon--right"></i> </el-button>
            <el-dropdown-menu slot="dropdown">
                <el-dropdown-item>
                    <el-upload
                        :multiple="multiple"
                        :disabled="disabled"
                        :action="uploadImgUrl"
                        list-type="text"
                        :on-success="handleUploadSuccess"
                        :before-upload="handleBeforeUpload"
                        :limit="limit"
                        :on-error="handleUploadError"
                        :on-exceed="handleExceed"
                        name="file"
                        :show-file-list="false"
                        :headers="headers"
                    >
                        <div>本地图片</div>
                    </el-upload>
                </el-dropdown-item>
                <el-dropdown-item>
                    <div @click="imgVisible = true">网络图片</div>
                </el-dropdown-item>
            </el-dropdown-menu>
        </el-dropdown>

        <div class="component-upload-image">
            <div class="upload-img-wrap">
                <draggable v-model="fileList" v-if="drag">
                    <transition-group name="list-complete" class="list-complete" tag="ul">
                        <li v-for="(file, index) in fileList" :key="index" class="list-complete-item">
                            <el-tooltip content="" placement="right">
                                <el-image :src="file.url" class="upload-img-add"></el-image>
                                <el-image :src="file.url" class="upload-img-big" slot="content"></el-image>
                            </el-tooltip>
                            <el-row type="flex" justify="space-between" style="width: 100%; padding: 4px 16px; margin-top: 8px">
                                <el-tooltip :content="`${index == 0 ? '' : '设为'}主图`" placement="top">
                                    <i class="el-icon-s-home" :style="{ color: index == 0 ? '#11a983' : '#666', 'font-size': '18px' }" @click="setMainImg(index)"></i>
                                </el-tooltip>
                                <el-tooltip :content="`删除`" placement="top">
                                    <i class="el-icon-delete" style="color: #666; font-size: 18px" @click="handleRemove(file, index)"></i>
                                </el-tooltip>
                            </el-row>
                        </li>
                    </transition-group>
                </draggable>
                <el-upload
                    class="hide"
                    action="#"
                    list-type="picture-card"
                    :show-file-list="true"
                    :limit="limit"
                    :on-exceed="handleExceed"
                    :on-preview="handlePictureCardPreview"
                    :on-remove="handleRemove"
                    :file-list="fileList"
                    v-else
                >
                    <div class="upload-img-add">
                        <i class="el-icon-plus"></i>
                        <div style="text-align: center">暂无图片</div>
                    </div>
                </el-upload>
                <el-upload :disabled="true" action="#" list-type="picture-card" v-if="fileList.length == 0">
                    <div class="upload-img-add">
                        <i class="el-icon-plus"></i>
                        <div style="text-align: center">暂无图片</div>
                    </div>
                </el-upload>
            </div>

            <!-- 上传提示 -->
            <div class="el-upload__tip" slot="tip" v-if="showTip">
                请上传
                <template v-if="fileSize">
                    大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
                </template>
                <template v-if="fileType">
                    格式为 <b style="color: #f56c6c">{{ fileType.join('/') }}</b>
                </template>
                的文件
            </div>

            <el-image-viewer v-if="dialogVisible" :on-close="closeViewer" :url-list="previewUrls" :initialIndex="previewIndex" :z-index="3000" />
        </div>
        <el-dialog :visible.sync="imgVisible" title="从网络地址(URL)选择图片" width="600" append-to-body v-loading="save">
            <template v-if="multiple">
                <el-input type="textarea" v-model="urlImgs" :rows="8" placeholder="请填写URL地址，多个地址回车换行"></el-input>
            </template>
            <template v-else>
                <el-input v-model.trim="urlImgs" placeholder="请填写URL地址"></el-input>
            </template>

            <div slot="footer" class="dialog-footer">
                <el-button type="primary" :loading="save" :disabled="save" @click="uploadUrlImages">添加</el-button>
                <el-button @click="imgVisible = false">取 消</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
import { getToken } from '@/utils/auth'
import { uploadUrlImages } from '@/api/product'
import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
import draggable from 'vuedraggable'
export default {
    components: { ElImageViewer, draggable },
    props: {
        value: [String, Object, Array],
        // 图片数量限制
        limit: {
            type: Number,
            default: 1,
        },
        // 大小限制(MB)
        fileSize: {
            type: Number,
            default: 5,
        },
        // 文件类型, 例如['png', 'jpg', 'jpeg']
        fileType: {
            type: Array,
            default: () => ['png', 'jpg', 'jpeg'],
        },
        // 是否显示提示
        isShowTip: {
            type: Boolean,
            default: true,
        },
        disabled: Boolean,
        multiple: {
            type: Boolean,
            default: true,
        },
        drag: false,
    },
    data() {
        return {
            imageModel: '',
            urlImgs: '',
            dialogImageUrl: '',
            previewUrls: [],
            previewIndex: 0,
            imgVisible: false,
            save: false,
            dialogVisible: false,
            hideUpload: false,
            uploadImgUrl: process.env.VUE_APP_BASE_API + '/api/UploadInfo/uploadImages', // 上传的图片服务器地址
            headers: {
                token: getToken(),
            },
            fileList: [],
            isShowFileList: true,
        }
    },
    watch: {
        value: {
            handler(val) {
                if (val) {
                    // 首先将值转为数组
                    const list = Array.isArray(val) ? val : this.value.split(',')
                    // 然后将数组转为对象数组
                    this.fileList = list.map(item => {
                        if (typeof item === 'string') {
                            item = { name: item, url: item, hover: false }
                        }
                        return item
                    })
                } else {
                    this.fileList = []
                    return []
                }
            },
            deep: true,
            immediate: true,
        },
    },
    computed: {
        // 是否显示提示
        showTip() {
            return this.isShowTip && (this.fileType || this.fileSize)
        },
    },
    methods: {
        changeImageModel() {
            if (this.imageModel === 'onlineImage') {
                this.imgVisible = true
            }
        },
        uploadUrlImages() {
            this.save = true
            const params = {
                images_urls: this.urlImgs,
            }
            uploadUrlImages(params)
                .then(res => {
                    if (res.code != 0) {
                        if (!this.multiple) {
                            this.fileList = []
                        }
                        res.data.map(item => {
                            this.fileList.push({
                                name: item,
                                url: item,
                                hover: false,
                            })
                        })

                        let result = {
                            list: this.listToString(this.fileList),
                            limit: this.limit,
                        }
                        this.urlImgs = ''
                        this.$emit('uploadInput', result)
                        //返回 v-model的参数（关键）
                        this.$emit('input', this.listToString(this.fileList))
                    }
                })
                .finally(() => {
                    this.save = false
                    this.imgVisible = false
                })
        },
        setMainImg(index) {
            const beforeItem = this.fileList[0]
            const afterItem = this.fileList[index]
            this.fileList[0] = afterItem
            this.fileList.splice(index, 1, beforeItem)
            this.$emit('uploadInput', {
                list: this.listToString(this.fileList),
                limit: this.limit,
            })
            //返回 v-model的参数（关键）
            this.$emit('input', this.listToString(this.fileList))
        },
        // 删除图片
        handleRemove(file, fileList) {
            const findex = this.fileList.map(f => f.name).indexOf(file.name)
            this.fileList.splice(findex, 1)
            this.$emit('uploadInput', {
                list: this.listToString(this.fileList),
                limit: this.limit,
            })
            //返回 v-model的参数（关键）
            this.$emit('input', this.listToString(this.fileList))
        },
        // 上传成功回调
        handleUploadSuccess(res) {
            if (res.code != 0) {
                if (!this.multiple) {
                    this.fileList = []
                }
                this.fileList.push({
                    name: res?.fileName ?? '',
                    url: res.data,
                })
                let result = {
                    list: this.listToString(this.fileList),
                    limit: this.limit,
                }
                this.$emit('uploadInput', result)
                //返回 v-model的参数（关键）
                this.$emit('input', this.listToString(this.fileList))
            } else {
                this.isShowFileList = false
                this.fileList = []
                this.$message({
                    type: 'error',
                    message: res.msg,
                })
            }

            this.loading.close()
        },
        // 上传前loading加载
        handleBeforeUpload(file) {
            let isImg = false
            if (this.fileType.length) {
                let fileExtension = ''
                if (file.name.lastIndexOf('.') > -1) {
                    fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
                }
                isImg = this.fileType.some(type => {
                    if (file.type.indexOf(type) > -1) return true
                    if (fileExtension && fileExtension.indexOf(type) > -1) return true
                    return false
                })
            } else {
                isImg = file.type.indexOf('image') > -1
            }

            if (!isImg) {
                this.$message.error(`文件格式不正确, 请上传${this.fileType.join('/')}图片格式文件!`)
                return false
            }
            if (this.fileSize) {
                const isLt = file.size / 1024 / 1024 < this.fileSize
                if (!isLt) {
                    this.$message.error(`上传头像图片大小不能超过 ${this.fileSize} MB!`)
                    return false
                }
            }
            this.loading = this.$loading({
                lock: true,
                text: '上传中',
                background: 'rgba(0, 0, 0, 0.7)',
            })
        },
        // 文件个数超出
        handleExceed() {
            this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`)
        },
        // 上传失败
        handleUploadError() {
            this.$message({
                type: 'error',
                message: '上传失败',
            })
            this.loading.close()
        },
        // 预览
        handlePictureCardPreview(file) {
            this.previewUrls = this.fileList.map(pre => pre.url)
            this.previewIndex = this.fileList.findIndex(pre => pre.name === file.name)
            this.dialogVisible = true
        },
        closeViewer() {
            this.dialogVisible = false
        },
        // 对象转成指定字符串分隔
        listToString(list, separator) {
            let strs = ''
            separator = separator || ','
            for (const i in list) {
                strs += list[i].url + separator
            }
            return strs != '' ? strs.substr(0, strs.length - 1) : ''
        },
    },
}
</script>
<style scoped lang="scss">
.list-complete {
    .list-complete-item {
        display: inline-flex;
        border: 1px solid #f5f5f5;
        width: 148px;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        margin-right: 12px;
    }
}
// .el-upload--picture-card 控制加号部分
::v-deep.hide .el-upload--picture-card {
    display: none;
}
// 去掉动画效果
::v-deep .el-list-enter-imageModel,
::v-deep .el-list-leave-imageModel {
    transition: all 0s;
}

::v-deep .el-list-enter,
.el-list-leave-imageModel {
    opacity: 0;
    transform: translateY(0);
}
.upload-img-wrap {
    margin: 8px 0;
    display: flex;
}
.upload-img-big {
    width: 500px;
    height: 500px;
}
.upload-img-add {
    width: 146px;
    height: 146px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    > div {
        margin-top: 8px;
        line-height: 2;
    }
}
</style>
